package br.ucb.cm.board.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JPanel;
import javax.swing.border.LineBorder;

import br.ucb.cm.board.bean.Location;
import br.ucb.cm.config.bean.BoardConfig;
import br.ucb.cm.config.bean.PieceConfig;
import br.ucb.cm.main.common.GeneralConstants;

public abstract class BoardPane extends JPanel implements MouseListener{
	private static final long serialVersionUID = 1L;
	
	protected int boardWidth;
	protected int boardHeight;
	protected List<SquarePane> squarePanes;
	protected BoardController controller;
	protected int defaultDimension;
	
	public BoardPane(int width, int height, BoardController controller) {
		this.boardWidth = width;
		this.boardHeight = height;
		this.squarePanes = new ArrayList<SquarePane>();
		this.controller = controller;
		this.defaultDimension = GeneralConstants.DEFAULT_SQUARE_DIMENSION;
		initComponents();
	}

	protected void initComponents() {
		mountSquareList();
		setBorder(new LineBorder(new Color(0, 0, 0)));
		setLayout(new GridLayout(boardHeight, boardWidth, 0, 0));

		removeAll();
		for (SquarePane pane : squarePanes)
			add(pane);

		fixDimension(defaultDimension);
	}

	protected void mountSquareList() {
		squarePanes.clear();

		for (int i = 0; i < boardHeight; i++)
			for (int j = 0; j < boardWidth; j++)
				squarePanes.add(new SquarePane(
						defaultDimension,
						((i % 2 == 0) ? j % 2 == 1 : j % 2 == 0) ?
								GeneralConstants.DARK :
									GeneralConstants.LIGHT, this,
									new Location(j, i)
						));
	}
	
	protected void fixDimension(int dimensionType) {
		Dimension dimension = new Dimension(boardWidth * dimensionType, boardHeight * dimensionType);

		setMaximumSize(dimension);
		setMinimumSize(dimension);
		setPreferredSize(dimension);
	}
	
	public Map<Location, PieceConfig> getPieceMap() {
		Map<Location, PieceConfig> map = new Hashtable<Location, PieceConfig>();
		
		for (SquarePane squarePane : squarePanes)
			if (squarePane.getCurrentPiece() != null)
				map.put(squarePane.getLocal(), squarePane.getCurrentPiece());
		
		return map;

	}
	
	public boolean isEmpty() {
		for (SquarePane squarePane : squarePanes) 
			if (squarePane.getCurrentPiece() != null) 
				return false;
		
		return true;
	}
	
	public SquarePane getSquareByLocation(Location location) {
		for (SquarePane squarePane : squarePanes)
			if (squarePane.getLocal().equals(location)) 
				return squarePane;

		return null;
	}
	
	public void applyBoardConfig(BoardConfig board) {
		this.boardWidth = board.getWidth();
		this.boardHeight = board.getHeight();
		
		initComponents();
		revalidate();
		repaint();
	}
	
	public void setPieceMap(Map<Location, PieceConfig> map) {
		for (Entry<Location, PieceConfig> entry : map.entrySet()) {
			getSquareByLocation(entry.getKey()).setPiece(entry.getValue());
		}
	}
	
	public void setDimensionType(int dimensionType){
		for (SquarePane squarePane : squarePanes) {
			squarePane.setDimensionType(dimensionType);
		}
		
		fixDimension(dimensionType);
	}

	public BoardController getController() {
		return controller;
	}

	public void setController(BoardController controller) {
		this.controller = controller;
	}

	@Override
	public void mouseClicked(MouseEvent e) {
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}

	@Override
	public void mouseReleased(MouseEvent e) {
	}
	
	@Override
	public abstract void mousePressed(MouseEvent e);

}
